package com.mhkj.common.timer.service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.springframework.stereotype.Component;

import com.mhkj.base.amount.entity.ExamineStandard;
import com.mhkj.base.amount.service.ExamineStandardService;
import com.mhkj.base.earlyWarning.entity.EarlyWarning;
import com.mhkj.base.earlyWarning.service.EarlyWarningService;
import com.mhkj.base.messageRemind.service.MessageRemindService;
import com.mhkj.check.entity.FineDetail;
import com.mhkj.check.service.FineDetailService;
import com.mhkj.common.constant.Constants;
/*import com.mhkj.check.entity.FineDetail;
import com.mhkj.check.service.FineDetailService;*/
import com.mhkj.common.enums.MessageType;
import com.mhkj.common.enums.NodeProperty;
import com.mhkj.common.enums.PlanSate;
import com.mhkj.revise.function.service.FunctionPlanNodeService;
import com.mhkj.revise.plan.entity.PlanNode;
import com.mhkj.revise.professional.service.ProfessionalPlanNodeService;
import com.mhkj.workspace.notify.entity.Notify;
import com.mhkj.workspace.notify.service.NotifyService;
import com.mics.core.common.util.DateUtils;
import com.mics.core.system.organizational.bean.Employee;
import com.mics.core.system.organizational.service.OrgService;
import com.mics.core.system.rbac.service.DictionaryService;

/**
 * 计划状态更新
 * @author mics
 * @date 2018年8月23日
 * @version 1.0
 */
@Component
public class StateUpdateService {
	@Resource
	private ProfessionalPlanNodeService professionalPlanNodeService;
	@Resource
	private ExamineStandardService examineStandardService;
	@Resource
	private FineDetailService fineDetailService;
	@Resource
	private  OrgService orgService;
	@Resource
	private MessageRemindService messageRemindService;
	@Resource
	private EarlyWarningService earlyWarningService;
	@Resource
	private DictionaryService dictionaryService;
	@Resource
	private NotifyService notifyService;
	@Resource
	private FunctionPlanNodeService functionPlanNodeService;
	
	
	
	/**
	 * 产生罚款
	 * @author mics
	 * @date 2018年8月23日
	 * @version 1.0
	 * @param overdueDay 
	 * @param state 
	 * @param p 每天罚款
	 */
	@Transactional
	public void productOverdueMoney(PlanNode pp, int state, int overdueDay){
		List<ExamineStandard> examineStandards = examineStandardService.findAll(); 
		if(examineStandards != null && examineStandards.size() > 0){
			for(ExamineStandard examineStandard: examineStandards){
				if(examineStandard.getKeyProperty().getId() == pp.getNodeProperty().getId()){
					List<Employee> employees = orgService.getEmployeeByPost(pp.getPostId());
					//首选第一个人员
					if(employees != null && employees.size() > 0){
						List<PlanNode> planNodeTemps = professionalPlanNodeService.getSameNameNode(pp.getId());
						for(PlanNode planNodeTemp:planNodeTemps){
							//产生罚款明细
							FineDetail fineDetail = new FineDetail();
							Employee employee = employees.get(0);
							fineDetail.setName(employee.getName());
							fineDetail.setEmployeeId(employee.getId());
							fineDetail.setPlanNode(planNodeTemp);
							fineDetail.setMoney(String.valueOf(examineStandard.getAmount()));
							fineDetail.setRemark(planNodeTemp.getNodeName()+"，未能按时完成任务");
							fineDetail.setDay(overdueDay);
							fineDetail.setRate(pp.getRate());
							fineDetailService.save(fineDetail);
							//修改罚款金额
							String fineMoney = new BigDecimal(examineStandard.getAmount()).multiply(new BigDecimal(overdueDay)).setScale(0,RoundingMode.HALF_UP).toString();
							planNodeTemp.setFineMoney(fineMoney);
							planNodeTemp.setState(state);
							planNodeTemp.setOverDay(overdueDay);
							professionalPlanNodeService.edit(planNodeTemp);
						}
						//产生罚款消息
						String content = "您的计划名称为"+pp.getNodeName()+" 今日被考核  金额 ("+examineStandard.getAmount()+"元),请尽快处理";
						productMessage(MessageType.FINE,content,1,employees.get(0).getId(),pp);
				}
			}
			
			}
		}

	}
	
	/**
	 * 产生消息
	 * @author mics
	 * @date 2018年8月23日
	 * @version 1.0
	 * @param MessageType  消息类型
	 * @param content 消息内容
	 * @param method 消息来源 1、系统发送  2、人员发送
	 * @param planNode  关联计划节点
	 */
	@Transactional
	public void productMessage(MessageType messageType,String content,int method,String acceptUserId, PlanNode planNode){
		Notify notify = new Notify();
		notify.setMethod(1);
		notify.setType(messageType.getState());
		notify.setContent(content);
		notify.setAcceptUserId(acceptUserId);
		notify.setPlanNode(planNode);
		notify.setsName("系统");
		notifyService.save(notify);
	}

		
	
	/**
	 * 检查是否逾期
	 * @author mics
	 * @date 2018年9月12日
	 * @version 1.0
	 */
	@Transactional
	public void overdueCheck() {
		List<PlanNode> planNodes = new ArrayList<PlanNode>();
		List<PlanNode> professionPlanNodes = professionalPlanNodeService.listAllChecked(); //审核通过的专项节点
		planNodes.addAll(professionPlanNodes);
		List<PlanNode> funPlanNodes = functionPlanNodeService.listAllChecked();//审核通过得职能计划节点
		planNodes.addAll(funPlanNodes);
		Date now = DateUtils.getDateYMD(new Date(), "yyyy-MM-dd");
		for(PlanNode planNode:planNodes){ 
			int overdueDay = DateUtils.compareDay(now, DateUtils.addDay(planNode.getEndDate(), planNode.getDelayDay()));
			if(overdueDay > 0 && (planNode.getState() == PlanSate.running.getState() || planNode.getState() == PlanSate.overdue.getState() )){  //逾期
				productOverdueMoney(planNode,PlanSate.overdue.getState(),overdueDay);
			}
		}
	}

	/**
	 * 风控检查
	 * @author mics
	 * @date 2018年9月12日
	 * @version 1.0
	 */
	@Transactional
	public void riskCheck() {
		List<PlanNode> planNodes = new ArrayList<PlanNode>();
		List<PlanNode> professionPlanNodes = professionalPlanNodeService.listAllChecked(); //审核通过的专项节点
		planNodes.addAll(professionPlanNodes);
		List<PlanNode> funPlanNodes = functionPlanNodeService.listAllChecked();//审核通过得职能计划节点
		planNodes.addAll(funPlanNodes);
		for(PlanNode planNode:planNodes){ 
			if(planNode.getState() == PlanSate.running.getState()){
				riskHandler(planNode); //风险检查
			}
			if(planNode.getState() == PlanSate.overdue.getState()){//失控检查
				if(planNode.getOverDay() > Constants.DELAY){
					List<PlanNode> planNodeTemps = professionalPlanNodeService.getSameNameNode(planNode.getId());
					for(PlanNode planNodeTemp:planNodeTemps){
						planNodeTemp.setRiskState(2);
						professionalPlanNodeService.edit(planNodeTemp);
					}
					//发送风险提醒
					List<Employee> employees = orgService.getEmployeeByPost(planNode.getPostId());
					if(employees != null && employees.size() > 0){
						String content = "您的计划名称为"+planNode.getNodeName()+" 状态为（失控），请尽快处理";
						productMessage(MessageType.RISK,content,1,employees.get(0).getId(),planNode);
					}
				}
			}		
		}
	}
	
	
	/**
	 * 预警状态
	 * @author mics
	 * @date 2018年8月28日
	 * @version 1.0
	 */
	@Transactional
	public void  riskHandler(PlanNode planNode){
		Date now = DateUtils.getDateYMD(new Date(), "yyyy-MM-dd");
		//风险检查
		if(planNode.getNodeProperty().getCode().equals(NodeProperty.NFUNC.getCode())){
			planNode.setDeadline(DateUtils.compareDay(planNode.getEndDate(), planNode.getBeginDate()));
		}
		List<EarlyWarning> earlyWarnings = earlyWarningService.findAll(); 
		for(EarlyWarning earlyWarning : earlyWarnings){
			int useDay = DateUtils.compareDay(now, planNode.getBeginDate());
			double deadlineRate = (double)useDay/planNode.getDeadline()*100.0;
			if(deadlineRate >= earlyWarning.getWorkDayLeast() && deadlineRate < earlyWarning.getWorkDayMax() && planNode.getRate() < earlyWarning.getSchedule()){
				List<PlanNode> planNodeTemps = professionalPlanNodeService.getSameNameNode(planNode.getId());
				for(PlanNode planNodeTemp:planNodeTemps){
					planNodeTemp.setRiskState(1);
					professionalPlanNodeService.edit(planNodeTemp);
				}
				//发送风险提醒
				List<Employee> employees = orgService.getEmployeeByPost(planNode.getPostId());
				if(employees != null && employees.size() > 0){
					String content = "您的计划名称为"+planNode.getNodeName()+" 状态为（有风险），请尽快处理";
					productMessage(MessageType.RISK,content,1,employees.get(0).getId(),planNode);
				}
			}
		}
	
	}

	/**
	 * 检查计划是否开始 
	 * @author mics
	 * @date 2018年9月12日
	 * @version 1.0
	 */
	@Transactional
	public void planBeginCheck() {
		List<PlanNode> planNodes = new ArrayList<PlanNode>();
		List<PlanNode> professionPlanNodes = professionalPlanNodeService.listAllChecked(); //审核通过的专项节点
		planNodes.addAll(professionPlanNodes);
		List<PlanNode> funPlanNodes = functionPlanNodeService.listAllChecked();//审核通过得职能计划节点
		planNodes.addAll(funPlanNodes);
		Date now = DateUtils.getDateYMD(new Date(), "yyyy-MM-dd");
		for(PlanNode planNode :planNodes){
			int cday = DateUtils.compareDay(now, planNode.getBeginDate());
			if(cday >= 0 && planNode.getState() == PlanSate.NoBegin.getState()){
				List<PlanNode> planNodeTemps = professionalPlanNodeService.getSameNameNode(planNode.getId());
				for(PlanNode planNodeTmep:planNodeTemps){
					planNodeTmep.setState(PlanSate.running.getState());
					professionalPlanNodeService.edit(planNodeTmep);
				}
				//发送待办提醒
				List<Employee> employees = orgService.getEmployeeByPost(planNode.getPostId());
				if(employees != null && employees.size() > 0){
					String content = planNode.getNodeName()+"已经开始，请及时处理";
					productMessage(MessageType.PREAPARE,content,1,employees.get(0).getId(),planNode);
				}
			}		
		}
		
	}
	
	/**
	 * 汇报提醒检查
	 * @author mics
	 * @date 2018年9月12日
	 * @version 1.0
	 */
	@Transactional
	public void huibaoCheck() {
		List<PlanNode> planNodes = new ArrayList<PlanNode>();
		List<PlanNode> professionPlanNodes = professionalPlanNodeService.listAllChecked(); //审核通过的专项节点
		planNodes.addAll(professionPlanNodes);
		List<PlanNode> funPlanNodes = functionPlanNodeService.listAllChecked();//审核通过得职能计划节点
		planNodes.addAll(funPlanNodes);
		Date now = DateUtils.getDateYMD(new Date(), "yyyy-MM-dd");
		for(PlanNode planNode:planNodes){
			if(DateUtils.addDay(planNode.getEndDate(), planNode.getDelayDay()).equals(now)){
				//发送汇报提醒
				List<Employee> employees = orgService.getEmployeeByPost(planNode.getPostId());
				if(employees != null && employees.size() > 0){
					String content = "您的计划名称为"+planNode.getNodeName()+" 今天为截止日期，请进行完成填报";
					productMessage(MessageType.PROGRESUBMIT, content, 1, employees.get(0).getId(), planNode);
				}
			}
		}		
	}
	
}
